<!doctype html>
<html>
    <head>
        <title>HT 组件面板手册</title>
        <meta charset="UTF-8">    
        <meta name="viewport" content="user-scalable=yes, width=1024">
        <style type="text/css"> 
            h1, h2, h3, h4, h5, h6, p, blockquote {
                margin: 0;
                padding: 0;
            }
            body {
                font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
                font-size: 13px;
                line-height: 18px;
                color: #737373;
                background-color: white; 
                margin: 10px 13px 10px 13px;
            }
            table {
                margin: 10px 0 15px 0;
                border-collapse: collapse;
            }
            td,th {	
                border: 1px solid #ddd;
                padding: 3px 10px;
            }
            th {
                padding: 5px 10px;	
            }
            a {
                color: #0069d6;
            }
            a:hover {
                color: #0050a3;
                text-decoration: none;
            }
            a img {
                border: none;
            }
            p {
                margin-bottom: 9px;
            }
            h1, h2, h3, h4, h5, h6 {
                color: #404040;
                line-height: 36px;
            }
            h1 {
                margin-bottom: 18px;
                font-size: 30px;
            }
            h2 {
                font-size: 24px;
            }
            h3 {
                font-size: 18px;
            }
            h4 {
                font-size: 16px;
            }
            h5 {
                font-size: 14px;
            }
            h6 {
                font-size: 13px;
            }
            hr {
                margin: 0 0 19px;
                border: 0;
                border-bottom: 1px solid #ccc;
            }
            blockquote {
                padding: 13px 13px 21px 15px;
                margin-bottom: 18px;
                font-family:georgia,serif;
                font-style: italic;
            }
            blockquote:before {
                content:"\201C";
                font-size:40px;
                margin-left:-10px;
                font-family:georgia,serif;
                color:#eee;
            }
            blockquote p {
                font-size: 14px;
                font-weight: 300;
                line-height: 18px;
                margin-bottom: 0;
                font-style: italic;
            }
            code, pre {
                font-family: Monaco, Andale Mono, Courier New, monospace;
            }
            code {
                background-color: #fee9cc;
                color: rgba(0, 0, 0, 0.75);
                padding: 1px 3px;
                font-size: 12px;
                border-radius: 3px;
            }
            pre {
                display: block;
                padding: 14px;
                margin: 0 0 18px;
                line-height: 16px;
                font-size: 11px;
                border: 1px solid #d9d9d9;
                white-space: pre-wrap;
                word-wrap: break-word;
            }
            pre code {
                background-color: #fff;
                color:#737373;
                font-size: 11px;
                padding: 0;
            }
            sup {
                font-size: 0.83em;
                vertical-align: super;
                line-height: 0;
            }
            * {
                -webkit-print-color-adjust: exact;
            }
            @media screen and (min-width: 914px) {
                body {
                    width: 854px;
                    margin:10px auto;
                }
            }
            @media print {
                body,code,pre code,h1,h2,h3,h4,h5,h6 {
                    color: black;
                }
                table, pre {
                    page-break-inside: avoid;
                }
            }                        
            iframe{
                width: 100%;
                border: 1px solid #34495E;
                margin: 0;                
            }            
            .logo{
                vertical-align: middle;
            }

        </style>        
        <script>
            function init() {
                var logoSrc = '',
                    logos = document.querySelectorAll('.logo'),
                    i = 0;
                for (; i < logos.length; i++) {
                    logos[i].src = logoSrc;
                }
                
                var iframes = document.querySelectorAll('iframe'),
                    func = function(){};
                for (i=0; i < iframes.length; i++) {
                    var iframe = iframes[i];
                    
                    // a small hack to make it work on android
                    iframe.ontouchstart = func;
                    
                    var div = document.createElement('div');
                    div.innerHTML = '<a href="' + iframe.src + '" target="_blank">独立运行→</a>';
                    iframe.parentNode.insertBefore(div, iframe);
                }   
            }
        </script>    
    </head>
    <body onload="init();">
        <a href="http://www.hightopo.com"><img class="logo"></a>HT 组件面板手册
        <hr style="margin: 1px 0 20px 0">
<p>索引</p>

<ul><li><a href="#ref_description">概述</a></li><li><a href="#ref_sample">简单示例</a></li><li><a href="#ref_customstyle">自定义组件样式</a></li><li><a href="#ref_editor">配合GraphView做一个简单的编辑器</a></li></ul>

<hr/>

<div id="ref_description"></div>

<h3>概述</h3>

<p><code>ht.widget.Palette</code>又叫组件面板或调色板，类似于<code>Toolbar</code>，允许用户快速访问按钮或命令。<code>ht.widget.Palette</code>支持自定义样式
及单选、拖拽操作。
在正式使用<code>API</code>之前，您的页面里应该引入相关的<code>js</code>文件：</p>

<pre><code>&lt;script src=&quot;ht.js&quot;&gt;&lt;/script&gt; &lt;!--先引入ht.js--&gt;
&lt;script src=&quot;ht-cssanimation.js&quot;&gt;&lt;/script&gt; &lt;!--依赖cssanimation插件--&gt;
&lt;script src=&quot;ht-palette.js&quot;&gt;&lt;/script&gt;</code></pre>

<p><code>Palette</code>和<code>GraphView</code>类似，由<code>ht.DataModel</code>驱动，用<code>ht.Group</code>展示分组，<code>ht.Node</code>展示按钮元素。</p>

<p><code>DataModel</code>是整个<code>HT</code>框架唯一的数据模型，<code>SelectionModel</code>是<code>HT</code>框架唯一的选择模型,关于它们的用法可以参考<code>HT</code>入门手册，
这里不再赘述。我们看下<code>Palette</code>支持的<code>ht.Group</code>和<code>ht.Node</code>的<code>API</code>：</p>

<p>支持的<code>ht.Group</code>的<code>API</code>：</p>

<ul><li><code>name</code>通过<code>setName(newName)</code>和<code>getName()</code>操作，设置或获取分组名称，支持<code>html</code> 标签</li><li><code>expanded</code>通过<code>setExpanded(newExpanded)</code>和<code>isExpanded()</code>操作，设置或获取此组的合并展开状态</li><li><code>promptText</code>样式，表示当分组中没有按钮时要显示的提示文字，支持<code>html</code>标签，通过<code>setStyle(&quot;promptText&quot;, value)</code>和<code>getStyle(&quot;promptText&quot;)</code>操作</li></ul>

<p>支持的<code>ht.Node</code>的<code>API</code>：</p>

<ul><li><code>name</code>通过<code>setName(newName)</code>和<code>getName()</code>操作，设置或获取按钮名称，支持<code>html</code>标签</li><li><code>image</code>通过<code>setImage(newImage)</code>和<code>getImage()</code>操作，设置或获取按钮图片，支持<code>url</code>或<code>base64</code>或通过<code>ht.Default.setImage</code>注册的图片名</li><li><code>toolTip</code>表示按钮的工具提示内容，通过<code>setToolTip(&#39;toolTip&#39;)</code>和<code>getToolTip()</code>操作</li><li><code>parent</code>通过<code>setParent(newGroup)</code>和<code>getParent()</code>操作，设置当前节点所属的组</li><li><code>image.stretch</code> 通过<code>setStyle(&#39;image.stretch&#39;, value)</code>和<code>getStyle(&#39;image.stretch&#39;)</code>操作，此样式支持的枚举如下：<ul><li><code>fill</code>图片填充满整个按钮区域，如果图片宽高比例和矩形不一致会导致图片拉伸失真</li><li><code>uniform</code>图片始终保持原始宽高比例不变化，并尽量填充满按钮区域</li><li><code>centerUniform</code>当按钮区域大于图片尺寸时图片以原始大小绘制在中心位置，空间不够时采用<code>uniform</code>的绘制方式</li></ul></li></ul>

<p><code>ht.widget.Palette</code>本身提供一些<code>API</code>控制外观，列举如下：</p>

<ul><li><code>itemImageWidth</code>通过<code>setItemImageWidth(newWidth)</code>和<code>getItemImageWidth()</code>操作，控制所有按钮元素的宽度，默认为<code>70</code></li><li><code>itemImageHeight</code>通过<code>setItemImageHeight(newHeight)</code>和<code>getItemImageHeight()</code>操作，控制所有按钮元素的高度，默认为<code>50</code></li><li><code>itemImagePadding</code>通过<code>setItemImagePadding(newHeight)</code>和<code>getItemImageHeight()</code>操作，控制所有按钮元素图片与边框的距离，默认为<code>4</code></li><li><code>itemMargin</code>通过<code>setItemMargin(newMargin)</code>和<code>getItemMargin()</code>操作，控制按钮元素之间的间隔，默认为<code>10</code></li><li><code>layout</code>通过<code>setLayout(newLayout)</code>和<code>getLayout()</code>操作，控制按钮元素的布局方式，默认为<code>largeicons</code>，支持的枚举列表如下：<ul><li><code>largeicons</code> 大图标模式，这是默认值</li><li><code>smallicons</code> 小图标模式</li><li><code>iconsonly</code> 仅图标模式</li></ul></li><li><code>getDataModel()</code> 返回数据模型</li><li><code>getView()</code> 返回视图<code>div</code></li><li><code>redraw()</code> 强制刷新视图</li><li><code>handleDragAndDrop(e, state)</code> 重写此方法可以禁用<code>HTML5</code>原生的<code>Drag</code>和<code>Drop</code>事件并启用模拟的拖拽事件</li></ul>

<div id="ref_sample"></div>

<h3>简单示例</h3>

<p>接下来看一个简单的例子：</p>

<p><iframe src="examples/example_sample.html" style="height:200px"></iframe></p>

<pre><code>mapGroup.setName(&quot;Map&quot;);
for (var i = 1; i &lt; 3; i++) {
    var node = new ht.Node();
    node.setImage(&quot;res/map&quot; + i + &quot;.png&quot;);
    node.setName(&quot;map&quot; + i);
    dataModel.add(node);
    node.setParent(mapGroup);
}
dataModel.add(mapGroup);</code></pre>

<div id="ref_customstyle"></div>

<h3>自定义组件样式</h3>

<p>除了<code>概述章节</code>里提到配置参数，面板还支持使用全局的<code>htconfig</code>对象配置整体风格，可配置的参数如下：</p>

<ul><li><code>Color.titleIconBackground</code> 指定<code>HT</code>所有组件的标题<code>ICON</code>的颜色，如面板，对话框，<code>AccordionView</code>等</li><li><code>Color.titleBackground</code> 指定<code>HT</code>所有组件的标题栏的背景色，如面板，对话框，<code>AccordionView</code>等</li><li><code>Default.paletteTitleLabelColor</code> 指定调色板标题栏的文字颜色，默认为<code>Default.labelSelectColor</code></li><li><code>Default.paletteTitleLabelFont</code> 指定调色板标题栏的文字字体，默认为<code>Default.labelFont</code></li><li><code>Default.paletteTitleHeight</code> 指定调色板标题栏的高度，默认为<code>Default.widgetTitleHeight</code></li><li><code>Default.paletteTitleBackground</code> 指定调色板标题栏的背景色，默认为<code>Color.titleBackground</code></li><li><code>Default.paletteTitleHoverBackground</code> 指定鼠标划过调色板标题栏时的背景色，默认为<code>Color.titleBackground</code></li><li><code>Default.paletteContentLabelFont</code> 指定调色板内容区域的文字字体</li><li><code>Default.paletteContentLabelColor</code> 指定调色板内容区域的文字颜色</li><li><code>Default.paletteContentBackground</code> 指定调色板内容区域的背景色</li><li><code>Default.paletteSeparatorWidth</code> 指定标题栏分割线的宽度，默认为<code>1</code></li><li><code>Default.paletteSeparatorColor</code> 指定标题栏分割线的颜色，默认为<code>undefined</code></li><li><code>Default.paletteItemHoverBorderColor</code> 指定鼠标划过按钮元素时的边框颜色，默认为<code>Color.highlight</code></li><li><code>Default.paletteItemSelectBackground</code> 指定被选中的按钮元素的背景色，默认为<code>Color.highlight</code></li></ul>

<p><iframe src="examples/example_customstyle.html" style="height:250px"></iframe></p>

<pre><code>   &lt;script&gt;
        htconfig = {
            Default: {
                paletteTitleLabelColor: &#39;black&#39;,
                paletteContentBackground: &#39;rgb(240, 239, 238)&#39;,
                paletteTitleBackground: &#39;rgb(240, 239, 238)&#39;,
                paletteItemHoverBorderColor: &#39;rgb(199,199,199)&#39;,
                paletteItemSelectBackground: &#39;rgb(221, 221, 221)&#39;,
                paletteSeparatorColor: &#39;rgb(197, 193, 189)&#39;,
                paletteTitleHoverBackground: &#39;rgb(215, 214, 213)&#39;
            }
        }
    &lt;/script&gt;</code></pre>

<div id="ref_editor"></div>

<h3>配合GraphView做一个简单的编辑器</h3>

<p><iframe src="examples/example_editor.html" style="height:250px"></iframe></p>

<p>选中<code>Palette</code>上第一个<code>Node</code>，然后在右侧拓扑上单击可以创建与其<code>image</code>相同的<code>Node</code>;
<code>Palette</code>上第二个<code>Node</code>支持拖拽创建，我们可以将它拖拽到拓扑上，然后生成相同<code>image</code>的<code>Node</code>。</p>

<pre><code>/* 监听palette选择改变事件，将新选中的Node的image存入createNodeInteractor中，用于创建Node */
palette.sm().ms(function(e) {
    var selectedNode = palette.sm().ld();
    if (selectedNode) {
        createNodeInteractor._image = selectedNode.getImage();
    }
});

/* 如果Node的draggble设为true，Palette可以自动处理dragstart，但是dragover和drop事件需要我们处理 */
graphView.getView().addEventListener(&quot;dragover&quot;, function(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = &quot;copy&quot;;
});
graphView.getView().addEventListener(&quot;drop&quot;, function(e) {
    e.preventDefault();
    e.stopPropagation();
    /* Palette在dragstart中将事件对象的Text属性赋值为nodeid:id，其中id指拖拽的Node的id，这里需要取出来再做处理 */
    var id = e.dataTransfer.getData(&quot;Text&quot;).replace(/nodeid:/g, &quot;&quot;);
    if (id) {
        var paletteNode = palette.dm().getDataById(id),
            node = new ht.Node(),
            lp = graphView.lp(e);

        graphView.dm().add(node);
        node.setPosition(lp.x, lp.y);
        node.setImage(paletteNode.getImage());
    }
});</code></pre>

<p>上面的例子中使用了<code>HTML5</code>原生的<code>Drag</code>和<code>Drop</code>事件，很遗憾，<code>iOS</code>和<code>Android</code>设备上并不支持此类事件，所以<code>Palette</code>插件还提供了模拟的拖拽事件，可以完美兼容<code>PC</code>和手持终端，参考下面的例子：</p>

<p><iframe src="examples/example_editormockdrag.html" style="height:250px"></iframe></p>

<pre><code>/*
* 重写handleDragAndDrop方法，当state为end时，判断e是否在graphView的范围内，如果是，则创建Node
 */
palette.handleDragAndDrop = function(e, state) {
    if (state === &#39;end&#39;) {
        var bound = graphView.getView().getBoundingClientRect(),
            point = ht.Default.getClientPoint(e);

        if (ht.Default.containsPoint({
            x: bound.left,
            y: bound.top,
            width: bound.width,
            height: bound.height
        }, point)) {
            var paletteNode = this.sm().ld(),
                node = new ht.Node(),
                lp = graphView.lp(e);
            graphView.dm().add(node);
            node.setPosition(lp.x, lp.y);
            node.setImage(paletteNode.getImage());
        }
    }
};</code></pre>    <hr id="contact" style="margin: 20px 0 1px 0">
    <a href="http://www.hightopo.com"><img class="logo"></a>欢迎交流 <a href="mailto:service@hightopo.com">service@hightopo.com</a>
</body>
</html>
